package com.pzc.controller;

import com.google.code.kaptcha.Producer;
import com.pzc.entity.*;
import com.pzc.service.UserService;
import com.pzc.utils.DigestUtil;
import com.pzc.utils.TokenUtils;
import com.pzc.utils.WarehouseConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Api(value = "用户登录Controller",tags = "登录相关接口")
@RestController
public class LoginController {

    //注入,这个时候就会把配置类中的Defaultkaptchabean注入给它,为了生成验证码图片
    @Resource(name="captchaProducer")
    private Producer producer;

    //注入redis模板
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @ApiOperation(value = "获取验证码图片")
    @ApiResponses(value = { @ApiResponse(code = 200, message = "成功"), @ApiResponse(code = 501, message = "业务错误")
             })
    @GetMapping("/captcha/captchaImage")
    public void captchaImage(HttpServletResponse response){
        //把声名部分放到括号外面，因为后面要关它
        ServletOutputStream out = null;
        try {
            //生成验证码图片的文本
            String text = producer.createText();
            //使用验证码文本生成验证码图片，其中BufferdImage意思是缓冲图片，生成图片目前是在内存中
            BufferedImage image = producer.createImage(text);
            //将验证码文本保存到redis，因为前台输入的验证码要在redis中查看是否匹配
            //将验证码文本作为键保存到redis,设置键的过期时间为三十分钟
            stringRedisTemplate.opsForValue().set(text,"",60*30, TimeUnit.SECONDS);

        /*
        将验证码图片相应给前端：
         */
            //设置响应正文image/jpeg
            response.setContentType("image/jpeg");
            //将验证码图片写给前端
            out = response.getOutputStream();
            //使用响应对象的字节输出流写入验证码图片
            ImageIO.write(image,"jpg",out);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭字节输出流
                if(out!=null){
                    try{
                        out.close();
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                }
        }
    }

        //注入UserService
        @Resource
        private UserService userService;

        @Autowired
        private TokenUtils tokenUtils;
        //@responseBody：表示接收并封装注入前端传递的登录的用户信息json数据
    @PostMapping("/login")
    @ApiResponses(value = { @ApiResponse(code = 200, message = "登录成功",response = Result.class), @ApiResponse(code = 501, message = "业务错误")
    })
    @ApiOperation(value = "用户登录接口")
    public Result login(@RequestBody LoginUser loginUser){
        String code = loginUser.getVerificationCode();
        if(!stringRedisTemplate.hasKey(code)){
            return Result.err(Result.CODE_ERR_BUSINESS,"验证码错误");
        }

        //首先判断是否有账号
        User user = userService.queryUserByCode(loginUser.getUserCode());
        if(user!=null){
            //账号存在
                //判断密码之前先判断用户是否被审核了
                if(user.getUserState().equals(WarehouseConstants.USER_STATE_NOT_PASS))
                    return Result.err(Result.CODE_ERR_BUSINESS,"用户未审核!");
                else{
                    //拿到用户录入的密码
                    String userPwd = loginUser.getUserPwd();
                    //进行md5加密
                    userPwd = DigestUtil.hmacSign(userPwd);
                    if(userPwd.equals(user.getUserPwd())){
                        //密码合法，允许登录，此时用户登录后，一段时间内不让他反复登录,这个时候就要给用户生成token了
                        String token = tokenUtils.loginSign(new CurrentUser(user.getUserId(),user.getUserName(),user.getUserCode()),userPwd);
                        return Result.ok("登录成功",token);
                    }
                    else{
                        //密码错误
                        return Result.err(Result.CODE_ERR_BUSINESS,"密码错误");
                    }
                }

        }
        else{
            //账号不存在
            return Result.err(Result.CODE_ERR_BUSINESS,"账号不存在!");
        }
    }

    //获取当前登录的用户信息的url接口/curr-user
    //这个注解就是获取指定的请求头，并把请求头注入这个标注的参数
    /*
public  Result currentUser(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token)
    将请求头Token的值，注入到变量token
     */


    @GetMapping("/curr-user")
    @ApiOperation("获取当前用户的登录信息")
    public  Result currentUser(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
        //解析token，拿到封装了用户的current对象
        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
        return Result.ok(currentUser);
    }

    /*
    加载用户权限菜单树的url接口/user/auth-list，注意看，这里没有参数，咱们需要从token中拿用户信息，user_id
     */


//    @GetMapping("/user/auth-list")
//    @ApiOperation("加载用户权限菜单树")
//    public Result loadAuthTree(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
//        CurrentUser currentUser = tokenUtils.getCurrentUser(token);
//        int userId = currentUser.getUserId();
//        //执行业务
//        List<Auth> authTreeList = authService.authTreeByUid(userId);
////        响应
//        return Result.ok(authTreeList);
////        return Result.ok(authService.authTreeByUid(currentUser.getUserId()));
//    }

    @DeleteMapping("/logout")
    @ApiOperation("登出")
    public Result logout(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
        //从redis中删除键值对
        stringRedisTemplate.delete(token);
        return Result.ok("退出系统");
    }

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

}
